package com.suitsoft.ut.service.base;

import java.io.File;
import java.util.Date;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import jxl.Sheet;
import jxl.Workbook;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.google.common.collect.Lists;
import com.suitsoft.ut.commons.Constants;
import com.suitsoft.ut.commons.UserHolder;
import com.suitsoft.ut.dao.account.UserDao;
import com.suitsoft.ut.dao.base.CollegeDao;
import com.suitsoft.ut.dao.base.DisciplineDao;
import com.suitsoft.ut.dao.base.StudentDao;
import com.suitsoft.ut.dao.base.StudentTempDao;
import com.suitsoft.ut.entity.account.Role;
import com.suitsoft.ut.entity.account.User;
import com.suitsoft.ut.entity.base.College;
import com.suitsoft.ut.entity.base.Discipline;
import com.suitsoft.ut.entity.base.Student;
import com.suitsoft.ut.entity.base.StudentTemp;
import com.suitsoft.ut.service.ServiceException;
import com.suitsoft.ut.service.account.AccountManager;
import com.suitsoft.ut.util.DateUtils;
import com.suitsoft.ut.util.ExcelDataError;
import com.suitsoft.ut.util.ExcelTools;
import com.suitsoft.ut.util.StringUtils;

/**
 * 学生临时信息管理 
 *@author Suine
 */
@Service
@Transactional
public class StudentTempManager {
	/** 日志输出对象 */
	protected final Logger logger = LoggerFactory.getLogger(getClass());
	private final int COLS = 10;
	
	@Autowired
	private StudentTempDao dao;
	@Autowired
	private AccountManager accountManager;
	@Autowired
	private CollegeDao collegeDao;
	@Autowired
	private DisciplineDao disciplineDao;
	@Autowired
	private UserDao userDao;
	@Autowired
	private StudentDao studentDao;
	@Autowired
	private StudentManager studentManager;
	
	
	public void deleteAll(){
		dao.deleteAll();
	}

	public StudentTemp get(Long id){
		return dao.get(id);
	}
	
	public List<StudentTemp> get(List<Long> ids){
		return dao.get(ids);
	}
	
	public List<StudentTemp> getAll(){
		return dao.getAll();
	}
	
	public void save(StudentTemp temp){
		dao.save(temp);
	}
	
	/**
	 * 读取Excel信息
	 * @param file
	 * @param errors
	 * @return
	 */
	public List<ExcelDataStudent> handleData(File file,List<ExcelDataError> errors){
		// 打开Excel工作簿
		Workbook workbook = ExcelTools.openExcelWorkbook(file.getPath());
		Sheet sheet = workbook.getSheet(0);
		int rowCount = sheet.getRows();
		int colCount = sheet.getColumns();
		
		if (COLS != colCount) {
			errors.add(new ExcelDataError(1, "-", "Excel文件格式无效！"));
			throw new ServiceException("文件格式无效");
		}
		
		List<ExcelDataStudent> excelDatas = Lists.newArrayList();
		
		// 循环处理所有行, 将数据读入到内存中
		for (int i = 1; i < rowCount; i++) {
			try {
				ExcelDataStudent edl = new ExcelDataStudent(sheet, i);
				excelDatas.add(edl);
			} catch (ServiceException e) {
				logger.warn("文件中有空行，实际读到行数：" + i);
				errors.add(new ExcelDataError(i, "-", "文件中有空行，实际读到行数：" + i + 1));
				throw new ServiceException("文件中有空行，实际读到行数：" + i);
			}
			
		}
		// 关闭Excel工作簿
		ExcelTools.closeExcelWorkbook(workbook);
		checkData(excelDatas, errors);
		return excelDatas;
	}
	
	/**
	 * 检查数据合法性
	 * @param datas
	 * @param errors
	 */
	private void checkData(List<ExcelDataStudent> datas,List<ExcelDataError> errors){
		Set<ExcelDataStudent> setData = new HashSet<ExcelDataStudent>();
		int i = 0;
		for(ExcelDataStudent d : datas){
			i ++;
			if(StringUtils.isEmpty(d.getClasses())){
				errors.add(new ExcelDataError(i + 1,"班级","为空"));
			}
			if(StringUtils.isEmpty(d.getCollege())){
				errors.add(new ExcelDataError(i + 1,"学院","为空"));
			}
			if(StringUtils.isEmpty(d.getDepartment())){
				errors.add(new ExcelDataError(i + 1,"专业","为空"));
			}
			if(StringUtils.isEmpty(d.getInSchool())){
				errors.add(new ExcelDataError(i + 1,"入学时间","为空"));
			}else if(!DateUtils.isLegalDate(d.getInSchool())){
				errors.add(new ExcelDataError(i + 1,"入学时间","不合法"));
			}
			if(StringUtils.isEmpty(d.getName())){
				errors.add(new ExcelDataError(i + 1,"学生姓名","为空"));
			}
			if(StringUtils.isEmpty(d.getNo())){
				errors.add(new ExcelDataError(i + 1,"学号","为空"));
			}
			if(StringUtils.isEmpty(d.getYear())){
				errors.add(new ExcelDataError(i + 1,"年份","为空"));
			}else if(!StringUtils.isNumber(d.getYear())){
				errors.add(new ExcelDataError(i + 1,"年份","非法数字"));
			}
			
			if(setData.contains(d)){
				int inx = datas.indexOf(d);
				errors.add(new ExcelDataError(i,"-","与第" + (inx + 2) + "行的学号重复"));
			}else{
				setData.add(d);
			}
		}
	}
	
	/**
	 * 获取学生临时数据列表
	 * @return
	 */
	public  List<Map<String,Object>> getImpList(){
		return dao.getImpList();
	}
	
	public List<StudentTemp> findBy(String name,String value){
		return dao.findBy(name, value);
	}
	
	/**
	 * 保存数据到正式数据中.即保存到BD_表中.
	 * @param students
	 */
	public void saveData(List<StudentTemp> students) throws ServiceException{
		//可登陆角色
		Role ableLoginRole = getRoleByName(Constants.CN_ABLE_LOGIN_USER);
		//学生角色
		Role studentRole = getRoleByName(Constants.CN_STUDENT);;
		//时间角色
		Role timeContrlRole = getRoleByName(Constants.CN_TIME_ROLE);
		//权限 集
		List<Role> roles = Lists.newArrayList();
		roles.add(ableLoginRole);
		roles.add(studentRole);
		roles.add(timeContrlRole);
		
		Student student = null;
		User user = null;
		College college = null;
		Discipline discipline = null;
		for(StudentTemp st: students){
			college = collegeDao.isHaveCollgeNoNew(st.getCollege());
			discipline = disciplineDao.isHaveNoNew(college, st.getDepartment());
			student = new Student();
			student.copy(st);
			student.setDiscipline(discipline);
			
			user = new User();
			user.setCollegeCode(college.getId()+"");
			user.setEmail(st.getEmail());
			user.setLoginName(st.getNo());
			user.setName(st.getName());
			user.setPassword(Constants.DEFALT_PASSWORD);
			
			user.setRoleList(roles);
			accountManager.saveUser(user);
			
			student.setForUser(user);
			
			userDao.save(user);
			
			studentManager.save(student);
			
			//设置为已确认
			st.setIsConfirm(1L);
			dao.save(st);
		}
	}
	
	
	/**
	 * 获取权限集合
	 * @param name
	 * @return
	 */
	public Role getRoleByName(String name){
		List<Role> roles = accountManager.findRoleByGroupName(name);
		if(roles == null || roles.isEmpty()){
			throw new ServiceException("系统内置角色丢失：" + name);
		}else if(roles.size() != 1){
			throw new ServiceException("系统内置角色存在重复：" + name);
		}
		return roles.get(0);
	}
}

